package org.budo.graph.service.util;

import java.util.Map;

import org.budo.sharding.algorithm.WeightedRoundRobinMasterSlaveLoadBalanceAlgorithm;
import org.budo.sharding.datasource.MasterSlaveDataSourceFactoryBean;
import org.budo.support.lang.util.MapUtil;
import org.budo.support.lang.util.NumberUtil;
import org.budo.support.lang.util.ReflectUtil;
import org.budo.support.servlet.util.QueryStringUtil;
import org.springframework.context.ApplicationContext;

import com.alibaba.druid.support.json.JSONUtils;

import lombok.extern.slf4j.Slf4j;

/**
 * @author lmw
 */
@Slf4j
public class GraphShardingUtil {
    private static final boolean hasMasterSlaveClass = ReflectUtil.hasClass("org.budo.sharding.datasource.MasterSlaveDataSourceFactoryBean");

    public static String show(ApplicationContext applicationContext, String url) {
        if (!hasMasterSlaveClass) {
            return "not has class MasterSlaveDataSourceFactoryBean";
        }

        MasterSlaveDataSourceFactoryBean masterSlaveDataSource = applicationContext.getBean(MasterSlaveDataSourceFactoryBean.class);
        WeightedRoundRobinMasterSlaveLoadBalanceAlgorithm loadBalanceAlgorithm = (WeightedRoundRobinMasterSlaveLoadBalanceAlgorithm) masterSlaveDataSource.getLoadBalanceAlgorithm();
        String json = JSONUtils.toJSONString(loadBalanceAlgorithm.getDataSourceWeight());

        log.info("#33 url=" + url + ", json=" + json + ", applicationContext=" + applicationContext);
        return json;
    }

    public static String update(ApplicationContext applicationContext, String url) {
        Map<String, String> parameters = QueryStringUtil.queryStringToStringMap(url);
        Map<String, Integer> dataSourceWeight = MapUtil.stringIntegerMap(MapUtil.remove(parameters, "host", "port"));

        if (NumberUtil.allLessThan(dataSourceWeight.values(), 1)) {
            log.error("#42 url=" + url + ", allLessThan 1" + ", applicationContext=" + applicationContext);
            return "error-all-less-than-1"; // 不允许全部小于1
        }

        MasterSlaveDataSourceFactoryBean masterSlaveDataSource = applicationContext.getBean(MasterSlaveDataSourceFactoryBean.class);
        WeightedRoundRobinMasterSlaveLoadBalanceAlgorithm loadBalanceAlgorithm = (WeightedRoundRobinMasterSlaveLoadBalanceAlgorithm) masterSlaveDataSource.getLoadBalanceAlgorithm();
        Map<String, Integer> before = loadBalanceAlgorithm.getDataSourceWeight();
        loadBalanceAlgorithm.setDataSourceWeight(dataSourceWeight);
        WeightedRoundRobinMasterSlaveLoadBalanceAlgorithm.clearWeightCache();

        log.info("#53 " + before + " > " + dataSourceWeight + ", masterSlaveDataSource=" + masterSlaveDataSource + ", url=" + url + ", applicationContext=" + applicationContext);
        return "done";
    }
}